/*
 * Przykład demonstruje typy wektorowe zdefiniowane w pliku sdl_vectormap.h.
 * Typ mvector3f zachowuje się algebraicznie jak wektor, co jest pokazane.
 * Zbiór jego wartości nie jest przechowywany w obiekcie wektora, tylko w zewnętrznym buforze buffer.
 * Taki wektor działa jak wskaźnik opakowany w strukturę algebraiczną.
 */

#include <iostream>
#include <fstream>
#include <vector>
#include "NxPhysics.h"

using namespace std;

#include "sdl_vectormap.h"

int main(int argc,char ** argv){
#ifdef WIN32
	// w Windows po prostu nie widać outputu ;/
	ostream * of = &ofstream("vmoutput.txt");
#else
	ostream * of = (ostream*)(&cout);
#endif
	// wektor physxowy
	NxVec3 nxv(1.0,1.0,1.0);

	// dodatkowo rezerwujemy 5 wektorów
	mvector3fmap moja_mapa(3,"mapa",5);
	mvector3f * a = &moja_mapa[0];
	mvector3f * b = &moja_mapa[1];
	mvector3f * c = &moja_mapa[2];

	// dajemy im jakieś wartośći (które idą na dane w mapie)
	*a = mvector3f(2.0f,1.0f,-1.0f);
	*b = mvector3f(1.0f,2.0f,2.0f);
	*c = mvector3f(-1.0f,3.0f,1.0f);
	
	*of << "a=" << *a << endl;
	// macierz jednostkowa
	matrix3x3f mat(matrix3x3f::I);
	
	//macierz diagonalna
	mat.diag(1.0f,2.0f,4.0f);
	*of << "mat= " << endl<<  mat << endl;

	(*a)=mat*(*a);
	*of << "a=mat*a=" << (*a) << endl;
	*of << "b=" << (*b) << endl;
	*of << "c=" << (*c) << endl;
	// przypisanie wektora physxowego
	(*a)=nxv;
	*of << "z wektora NxVec3: a=" << (*a) << endl;

	// wykonujemy szereg operacji algebraicznych
	*a=((*a)^(*b))^mvector3f(1,0,0);
	*of << "a=(a^b)^(1,0,0)=" << *a << endl;

	*b=(*b)^(*c)^(-(*a))-(*a);
	*of << "b=b^c^(-a)-a=" << *b << endl ;

	*c=(mvector3f(0.0,0.0,1.0)&((*b)^(*c)));
	*of << "c=(0,0,1)&(b^c)=" << *c << endl;
	
	*c*=3.0;
	*of << "c*=3=" << *c << endl;	

	*b=*a+*b+*c ;
	*of << "b=a+b+c=" << *b << endl;
	// i patrzymy jak to się odzwierciedla na wyjściowym zbiorze
	*of << "mapa = " ;
	const float * buf = (const float*)(moja_mapa);
	for(int i=0;i<9;i++){
		*of << buf[i] << ", " ;
	}
	*of << endl;
	
	// ładnie się rozszerza?
	moja_mapa.insert(5);
	
	
	*of << endl;
	*of << "Najciekawsza część zabawy :)" << endl<<endl;
	// To jest chyba najfajniejsza część tej zabawy. Zbiór danych pozostaje taki sam, a możemy mapować jego obszary :)
	// testujemy mapowanie map przez mapy :)
	mvector3fmap inna_mapa = moja_mapa(2,5);

	// zobaczmy, czy nowa mapa czuje zmiany w starej
	for(int i=3;i<5;i++)
		moja_mapa[i]+=mvector3f(1,i,-1);

	*of << "Tak wygląda moja mapa [0,"<<moja_mapa.size()<<"):" << endl;
	*of << "moja_mapa.size()="<< moja_mapa.size() << endl;
	for(int i=0;i<moja_mapa.size();i++)
		*of << "moja_mapa["<<i<<"]="<<moja_mapa[i]<<endl;

	*of << "A tak się mapuje moja mapa [2,5): " << endl;
	*of << "inna_mapa.size()="<< inna_mapa.size() << endl;
	for(int i=0;i<inna_mapa.size();i++)
		*of << "inna_mapa["<<i<<"]="<<inna_mapa[i]<<endl;

#ifdef WIN32
	((ofstream*)(of))->close();
#endif
	return 0;
}
